/*
package com.companyName.sample.service.impl;

import com.companyName.sample.api.service.IFdsService;
import com.google.common.collect.LinkedListMultimap;
import com.xiaomi.infra.galaxy.fds.auth.Common;
import com.xiaomi.infra.galaxy.fds.auth.HttpMethod;
import com.xiaomi.infra.galaxy.fds.client.FDSClientConfiguration;
import com.xiaomi.infra.galaxy.fds.client.GalaxyFDSClient;
import com.xiaomi.infra.galaxy.fds.client.credential.GalaxyFDSCredential;
import com.xiaomi.infra.galaxy.fds.exception.GalaxyFDSClientException;
import com.xiaomi.infra.galaxy.fds.model.AccessControlList;
import com.xiaomi.infra.galaxy.fds.model.AccessControlList.Grant;
import com.xiaomi.infra.galaxy.fds.model.AccessControlList.GrantType;
import com.xiaomi.infra.galaxy.fds.model.AccessControlList.Permission;
import com.xiaomi.infra.galaxy.fds.model.FDSObjectMetadata;
import org.joda.time.DateTime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;

@Service
@Configuration
@ConfigurationProperties(ignoreUnknownFields = true, prefix = "xiaomifds")
public class FdsService  implements IFdsService {

	private static final Logger logger = LoggerFactory.getLogger(FdsService.class);

	private GalaxyFDSClient fdsClient;

	private String region;

	private String fdsId;

	private String fdsSecret;

	private Boolean enableHttps;
	
	private Boolean enableCdn;

	private int expiresMin;

	public String getRegion() {
		return region;
	}

	public void setRegion(String region) {
		this.region = region;
	}

	public String getFdsId() {
		return fdsId;
	}

	public void setFdsId(String fdsId) {
		this.fdsId = fdsId;
	}

	public String getFdsSecret() {
		return fdsSecret;
	}

	public void setFdsSecret(String fdsSecret) {
		this.fdsSecret = fdsSecret;
	}

	public Boolean getEnableHttps() {
		return enableHttps;
	}

	public void setEnableHttps(Boolean enableHttps) {
		this.enableHttps = enableHttps;
	}

	public Boolean getEnableCdn() {
		return enableCdn;
	}

	public void setEnableCdn(Boolean enableCdn) {
		this.enableCdn = enableCdn;
	}

	public int getExpiresMin() {
		return expiresMin;
	}

	public void setExpiresMin(int expiresMin) {
		this.expiresMin = expiresMin;
	}

	private GalaxyFDSClient getFdsClient() {
		if (this.fdsClient == null) {
			FDSClientConfiguration config = new FDSClientConfiguration();
			config.enableHttps(getEnableHttps());
			config.enableCdnForDownload(getEnableCdn());

			configRegion(config);
			
			this.fdsClient = new GalaxyFDSClient(new GalaxyFDSCredential() {
				@Override
				public String getGalaxyAccessId() {
					return getFdsId();
				}

				@Override
				public String getGalaxyAccessSecret() {
					return getFdsSecret();
				}
			}, config);
		}

		return fdsClient;
	}

	private void configRegion(FDSClientConfiguration config) {
		config.setRegionName(this.getRegion());
	}

	public String getUploadUrl(String bucketName, String objectName) {
		return getUploadUrl(bucketName, objectName, "");
	}

	public String getUploadUrl(String bucketName, String objectName, String contentType) {
		DateTime dt = DateTime.now().plusMinutes(getExpiresMin());
		try {
			LinkedListMultimap<String, String> headers = LinkedListMultimap.create();
			headers.put(Common.CONTENT_TYPE, contentType);

			/// xiaomi's engineers said that upload using cdn is not recommended
			URI uri = getFdsClient().generatePresignedUri(bucketName,
					objectName, dt.toDate(), HttpMethod.PUT, headers);
			String url = uri.toString();
			return url;
		} catch (GalaxyFDSClientException e) {
			logger.warn("generate upload uri for bucket \"{}\" and object \"{}\" failed: {}",
					new Object[] { bucketName, objectName, e.getMessage() });
			return null;
		}
	}

	public String getDownloadUrl(String bucketName, String objectName) {
		try {
			URI uri = getFdsClient().generateDownloadObjectUri(bucketName, objectName);
			// String url = URLEncoder.encode(uri.toString(), ReqUri.defaultEncoding);
			String url = uri.toString();
			return url;
		} catch (GalaxyFDSClientException e) {
			logger.warn("generate download uri for bucket \"{}\" and object \"{}\" failed: {}",
					new Object[] { bucketName, objectName, e.getMessage() });
			return null;
		}
	}

	public String getObjectFromUrl(String urlString, String bucketName) {
		URL url;
		try {
			url = new URL(urlString);
		} catch (MalformedURLException e) {
			logger.warn("illegal url string");
			return null;
		}

		String path = url.getPath();
		int index = path.indexOf(bucketName);
		if (index != -1) {
			return path.substring(index + bucketName.length() + 1, path.length());
		}

		return null;
	}

	public boolean setObjectVisible(String bucketName, String objectName) {
		try {
			getFdsClient().setPublic(bucketName, objectName, true);
		} catch (GalaxyFDSClientException e) {
			logger.warn("set the object {}/{} public failed: {}",
					new Object[] { bucketName, objectName, e.getMessage()});
			e.printStackTrace();
			return false;
		}
		
		try {
			getFdsClient().prefetchObject(bucketName, objectName);
		} catch (Exception ex) {
			logger.warn("prefetch object to CDN failed! {}", ex.getMessage());
			ex.printStackTrace();
		}

		return true;
	}

	public boolean refreshObjectToCdn(String bucketName, String objectName) {
		try {
			logger.info("refresh the object in CDN: {}/{}", bucketName, objectName);
			getFdsClient().refreshObject(bucketName, objectName);
			return true;
		} catch (GalaxyFDSClientException ex) {
			logger.warn("refresh object in CDN failed! {}", ex.getMessage());
			ex.printStackTrace();
			return false;
		}
	}

	public boolean setObjectHiden(String bucketName, String objectName) {
		AccessControlList acl = new AccessControlList();
		acl.addGrant(new Grant("",
				Permission.FULL_CONTROL,
				GrantType.USER));
		try {
			getFdsClient().setObjectAcl(bucketName, objectName, acl);
			return true;
		} catch (GalaxyFDSClientException e) {
			logger.warn("set the object {}/{} private failed: {}",
					new Object[] { bucketName, objectName, e.getMessage() });
			e.printStackTrace();
			return false;
		}
	}

	public boolean putObject(String bucketName, String objectName, InputStream is) {
		try {
			FDSObjectMetadata metadata = new FDSObjectMetadata();
			metadata.setContentType("application/octet-stream");
			getFdsClient().putObject(bucketName, objectName, is, metadata);
			return true;
		} catch (GalaxyFDSClientException e) {
			logger.warn("upload object {}/{} public failed: {}",
					new Object[] { bucketName, objectName, e.getMessage()});
			e.printStackTrace();
			return false;
		}
	}
	
	public boolean putObject(String bucketName, String objectName, InputStream is, String contentType) {
		try {
			FDSObjectMetadata metadata = new FDSObjectMetadata();
			metadata.setContentType(contentType);
			getFdsClient().putObject(bucketName, objectName, is, metadata);
			return true;
		} catch (GalaxyFDSClientException e) {
			logger.warn("upload object {}/{} public failed: {}",
					new Object[] { bucketName, objectName, e.getMessage()});
			e.printStackTrace();
			return false;
		}
	}

	public boolean deleteObject(String downloadUrl) {
		try {
			URI uri = new URI(downloadUrl);
			String bucketWithObject = uri.getPath();
			int index = bucketWithObject.indexOf('/', 1);
			String bucketName = bucketWithObject.substring(1, index);
			String objectName = bucketWithObject.substring(index + 1);
			getFdsClient().deleteObject(bucketName, objectName);
			return true;
		} catch (GalaxyFDSClientException | URISyntaxException e) {
			logger.warn("delete object by url: \"{}\" failed", downloadUrl);
			e.printStackTrace();
			return false;
		}
		
	}

	///
	/// putObjectInTrash: mark the given object deleted, but not delete it really 
	///
	public boolean putObjectInTrash(String bucket, String object) {
		try {
			String trashObject = String.format("trash/%s", object);
			getFdsClient().renameObject(bucket, object, trashObject);
			this.setObjectHiden(bucket, trashObject);
			return true;
		} catch (GalaxyFDSClientException e) {
			logger.warn("set the object {}/{} private failed: {}",
					new Object[] { bucket, object, e.getMessage() });
			e.printStackTrace();
			return false;
		}
	}
}
*/
